
//!============================================================================
//!<Interface> Vertex|Fragment
//!----------------------------------------------------------------------------

//!<Include> StdLight.sl

struct StdSpotLight {
	// Light colors
	StdLightColor Colors;
	// Light position
	vec3 Position;
	// Spot light direction
	vec3 SpotDirection;
	// Cosine of the spot cut-off
	float CosSpotCutoff;
	// Attenuation factors
	StdLightAttenuation Attenuation;
};

// Compute spot light contribution
void ComputeLightContribution(inout StdLightColor colors, StdSpotLight light, vec3 normal, vec3 eye, vec3 ecposition, float shiness);

//!============================================================================
//!<xSource> Vertex|Fragment
//!----------------------------------------------------------------------------

//<Include> Interface

void ComputeLightContribution(inout StdLightColor colors, StdSpotLight light, vec3 normal, vec3 eye, vec3 ecposition, float shininess)
{
	float NormalDotLightDir;
	float PowerFactor = 0.0;
	float Distance = length(light.Position.xyz - ecposition);
	float Attenuation = 1.0 / (light.Attenuation.Constant + (light.Attenuation.Linear * Distance) + (light.Attenuation.Quadratic * Distance * Distance));
	float SpotDot;
	vec3 LightDir = normalize(light.Position.xyz);

	// Surface inside the spot cone?
	if (dot(-LightDir, normalize(light.SpotDirection)) < light.CosSpotCutoff) {
		// Dot product between surface normal and light direction
		NormalDotLightDir = max(0.0, dot(normal, LightDir));
		
		// Contribute with ambient
		colors.Ambient += light.Colors.Ambient * Attenuation;
		// Contribute with diffuse
		colors.Diffuse += light.Colors.Diffuse * NormalDotLightDir * Attenuation;
		// Contribute with specular
		if ((NormalDotLightDir != 0.0) && (shininess != 0.0)) {
			vec3 HalfVector = normalize(LightDir + eye);
			float NormalDotLightHalf = max(0.0, dot(normal, HalfVector));

			colors.Specular += light.Colors.Specular * pow(NormalDotLightHalf, shininess) * Attenuation;
		}
	}
}

//!============================================================================
//! Implementation notes
//!----------------------------------------------------------------------------
//!
//!----------------------------------------------------------------------------
